import type { ILoginForm } from "@/api/login";
import type { IAuthLoginRes } from "@/api/types/login";
import { defineStore } from "pinia";
import { computed, ref } from "vue"; // 修复：导入 computed
import {
  login as _login,
  logout as _logout,
  refreshToken as _refreshToken,
  wxLogin as _wxLogin,
  getUserInfo,
  getWxCode,
  getWxUserInfo,
} from "@/api/login";
import { isDoubleTokenRes, isSingleTokenRes } from "@/api/types/login";
import { isDoubleTokenMode } from "@/utils";
import { useUserStore } from "./user";

// 初始化状态
const tokenInfoState = isDoubleTokenMode
  ? {
      accessToken: "",
      accessExpiresIn: 0,
      refreshToken: "",
      refreshExpiresIn: 0,
    }
  : {
      token: "",
      expiresTime: 0,
    };

export const useTokenStore = defineStore(
  "token",
  () => {
    // 定义用户信息
    const tokenInfo = ref<IAuthLoginRes>({ ...tokenInfoState });
    // 设置用户信息
    const setTokenInfo = (val: IAuthLoginRes) => {
      tokenInfo.value = val;
      // 计算并存储过期时间
      const now = Date.now();
      if (isSingleTokenRes(val)) {
        // 单token模式
        // const expireTime = now + val.expiresIn * 1000
        uni.setStorageSync("accessTokenExpireTime", val.expiresTime);
      } else if (isDoubleTokenRes(val)) {
        // 双token模式
        const accessExpireTime = now + val.accessExpiresIn * 1000;
        const refreshExpireTime = now + val.refreshExpiresIn * 1000;
        uni.setStorageSync("accessTokenExpireTime", accessExpireTime);
        uni.setStorageSync("refreshTokenExpireTime", refreshExpireTime);
      }
    };

    /**
     * 判断token是否过期
     */
    const isTokenExpired = computed(() => {
      if (!tokenInfo.value) {
        return true;
      }

      const now = Date.now();
      const expireTime = uni.getStorageSync("accessTokenExpireTime");

      if (!expireTime) return true;
      return now >= expireTime;
    });

    /**
     * 判断refreshToken是否过期
     */
    const isRefreshTokenExpired = computed(() => {
      if (!isDoubleTokenMode) return true;

      const now = Date.now();
      const refreshExpireTime = uni.getStorageSync("refreshTokenExpireTime");

      if (!refreshExpireTime) return true;
      return now >= refreshExpireTime;
    });

    /**
     * 登录成功后处理逻辑
     * @param tokenInfo 登录返回的token信息
     */
    async function _postLogin(codeInfo: object) {
      // setTokenInfo(tokenInfo)
      const userStore = useUserStore();
      const res = await userStore.fetchUserInfo(codeInfo);
      const tokenInfo: IAuthLoginRes = {
        token: res.token,
        expiresTime: res.expiresTime, // 过期时间
      };
      setTokenInfo(tokenInfo);
      return res;
    }

    /**
     * 用户登录
     * 有的时候后端会用一个接口返回token和用户信息，有的时候会分开2个接口，一个获取token，一个获取用户信息
     * （各有利弊，看业务场景和系统复杂度），这里使用2个接口返回的来模拟
     * @param loginForm 登录参数
     * @returns 登录结果
     */
    const login = async (loginForm: ILoginForm) => {
      try {
        const res = await _login(loginForm);
        console.log("普通登录-res: ", res);
        await _postLogin(res);
        uni.showToast({
          title: "登录成功",
          icon: "success",
        });
        return res;
      } catch (error) {
        console.error("登录失败:", error);
        uni.showToast({
          title: "登录失败，请重试",
          icon: "error",
        });
        throw error;
      }
    };

    /**
     * 微信登录
     * 有的时候后端会用一个接口返回token和用户信息，有的时候会分开2个接口，一个获取token，一个获取用户信息
     * （各有利弊，看业务场景和系统复杂度），这里使用2个接口返回的来模拟
     * @returns 登录结果
     */
    const wxLogin = async () => {
      try {
        // 获取微信小程序登录的code
        const { code } = await getWxCode();
        console.log("微信登录-code: ", code);
        const res = await getWxUserInfo();
        console.log("微信用户信息-res: ", res);

        const encryptedData = res.encryptedData;
        const iv = res.iv;
        const signature = res.signature;
        const rawData = res.rawData;
        // const res = await _wxLogin(code)
        // console.log('微信登录-res: ', res)
        await _postLogin({
          js_code: code,
          encryptedData,
          iv,
          signature,
          rawData,
        });
        // uni.showToast({
        //   title: '登录成功',
        //   icon: 'success',
        // })
        console.log("登录成功=====================");
        return res;
      } catch (error) {
        console.error("微信登录失败:", error);
        uni.showToast({
          title: "微信登录失败，请重试",
          icon: "error",
        });
        throw error;
      }
    };

    /**
     * 退出登录 并 删除用户信息
     */
    const logout = async () => {
      try {
        // TODO 实现自己的退出登录逻辑
        await _logout();
      } catch (error) {
        console.error("退出登录失败:", error);
      } finally {
        // 无论成功失败，都需要清除本地token信息
        // 清除存储的过期时间
        uni.removeStorageSync("accessTokenExpireTime");
        uni.removeStorageSync("refreshTokenExpireTime");
        console.log("退出登录-清除用户信息");
        tokenInfo.value = { ...tokenInfoState };
        uni.removeStorageSync("token");
        const userStore = useUserStore();
        userStore.clearUserInfo();
      }
    };

    /**
     * 刷新token
     * @returns 刷新结果
     */
    const refreshToken = async () => {
      wxLogin(); // 重新刷新token,获取用户信息
      // if (!isDoubleTokenMode) {
      //   console.error("单token模式不支持刷新token");
      //   throw new Error("单token模式不支持刷新token");
      // }

      // try {
      //   // 安全检查，确保refreshToken存在
      //   if (
      //     !isDoubleTokenRes(tokenInfo.value) ||
      //     !tokenInfo.value.refreshToken
      //   ) {
      //     throw new Error("无效的refreshToken");
      //   }

      //   const refreshToken = tokenInfo.value.refreshToken;
      //   const res = await _refreshToken(refreshToken);
      //   console.log("刷新token-res: ", res);
      //   setTokenInfo(res);
      //   return res;
      // } catch (error) {
      //   console.error("刷新token失败:", error);
      //   throw error;
      // }
    };

    /**
     * 获取有效的token
     * 注意：在computed中不直接调用异步函数，只做状态判断
     * 实际的刷新操作应由调用方处理
     */
    const getValidToken = computed(() => {
      // token已过期，返回空
      if (isTokenExpired.value) {
        return "";
      }

      if (!isDoubleTokenMode) {
        return isSingleTokenRes(tokenInfo.value) ? tokenInfo.value.token : "";
      } else {
        return isDoubleTokenRes(tokenInfo.value)
          ? tokenInfo.value.accessToken
          : "";
      }
    });

    /**
     * 检查是否有登录信息（不考虑token是否过期）
     */
    const hasLoginInfo = computed(() => {
      if (!tokenInfo.value) {
        return false;
      }
      if (isDoubleTokenMode) {
        return (
          isDoubleTokenRes(tokenInfo.value) && !!tokenInfo.value.accessToken
        );
      } else {
        return isSingleTokenRes(tokenInfo.value) && !!tokenInfo.value.token;
      }
    });

    /**
     * 检查是否已登录且token有效
     */
    const hasValidLogin = computed(() => {
      console.log("hasValidLogin", hasLoginInfo.value, !isTokenExpired.value);
      return hasLoginInfo.value && !isTokenExpired.value;
    });

    /**
     * 尝试获取有效的token，如果过期且可刷新，则刷新token
     * @returns 有效的token或空字符串
     */
    const tryGetValidToken = async (): Promise<string> => {
      if (
        !getValidToken.value &&
        isDoubleTokenMode &&
        !isRefreshTokenExpired.value
      ) {
        try {
          await refreshToken();
          return getValidToken.value;
        } catch (error) {
          console.error("尝试刷新token失败:", error);
          return "";
        }
      }
      return getValidToken.value;
    };

    return {
      // 核心API方法
      login,
      wxLogin,
      logout,

      // 认证状态判断（最常用的）
      hasLogin: hasValidLogin,

      // 内部系统使用的方法
      refreshToken,
      tryGetValidToken,
      validToken: getValidToken,

      // 调试或特殊场景可能需要直接访问的信息
      tokenInfo,
      setTokenInfo,
    };
  },
  {
    // 添加持久化配置，确保刷新页面后token信息不丢失
    persist: true,
  },
);
